package com.hk.web.controller.api;

import com.hk.commons.JsonResult;
import com.hk.commons.ProcessAPI;
import com.hk.commons.exceptions.SystemException;
import com.hk.commons.service.ImageCaptchaService;
import com.hk.web.controller.Routes;
import com.octo.captcha.CaptchaException;
import com.octo.captcha.service.CaptchaServiceException;

import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Locale;

/**
 * Created by Antinomy on 16/10/13.
 */

@RestController
@RequestMapping(Routes.CAPTCHA)
public class CaptchaController {

    private Logger logger = LoggerFactory.getLogger(CaptchaController.class);


    @Value("${captcha.image.path}")
    private String imgFolder;

    @Value("${captcha.image.url}")
    private String imgUrl;

    @RequestMapping(value = Routes.CAPTCHA_CODE, method = RequestMethod.GET)
    @ResponseBody
    public JsonResult genPicVerifyCode(HttpServletRequest request, @PathVariable String verifySource) {

        ProcessAPI api = (jsonResult, validate) -> {

            // get the session id that will identify the generated captcha.
            //the same id must be used to validate the response, the session id is a good candidate!
            String captchaId = validate.checkAndPrepare("verifySource", verifySource);

            try {

                jsonResult.result = createVerifyCode(captchaId);

            } catch (CaptchaException e) {
                //retry when fail create verify code
                jsonResult.result = createVerifyCode(captchaId);
            } catch (IllegalArgumentException e) {
                throw new SystemException("SC_NOT_FOUND");
            } catch (CaptchaServiceException e) {
                throw new SystemException("SC_INTERNAL_SERVER_ERROR");
            } catch (IOException e) {
                throw new SystemException(e.getMessage());
            }

        };

        return api.process(request);
    }


    @RequestMapping(value = Routes.CAPTCHA_VERIFICATION, method = RequestMethod.POST)
    @ResponseBody
    public JsonResult verification(HttpServletRequest request, @PathVariable String verifySource,String verifyCode) {

        ProcessAPI api = (jsonResult, validate) -> {
            String captchaId = validate.checkAndPrepare("verifySource", verifySource);
            String response = validate.checkAndPrepare("verifyCode", verifyCode);

            Boolean isResponseCorrect = Boolean.FALSE;

            // Call the Service method
            try {
                isResponseCorrect = ImageCaptchaService.getInstance().validateResponseForID(captchaId, response);
            } catch (CaptchaServiceException e) {
                //should not happen, may be thrown if the id is not valid
                throw new SystemException(e.getMessage());
            }

            jsonResult.result = isResponseCorrect;
        };

        return api.process(request);
    }

    private String createVerifyCode(String captchaId) throws IOException {
        // call the ImageCaptchaService getChallenge method
        BufferedImage bufferedImage = ImageCaptchaService.getInstance().getImageChallengeForID(captchaId, Locale.CHINA);

        String randomTxt = RandomStringUtils.randomAlphanumeric(24);
        String fileName = "image/captcha/" + randomTxt + ".png";

        String filePathName = imgFolder + fileName;
        logger.info("Path : " + filePathName);
        File file = new File(filePathName);
        ImageIO.write(bufferedImage,"png",file);

        return imgUrl+ fileName;
    }

}
